﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

using MINERP.MODEL.NewPinBan;
using LayoutDll;
using MINERP.COM;
using MINERP.MODEL.FoundationModel;
using MINERP.DAL;

namespace MINERP.BLL.NewPB
{
    using System.Data;
    using System.Data.Objects;
    using System.Data.SqlClient;
    using MINERP.COM.DBHelper;

    public class AutoPB
    {
        int printTech = (int)TechType.print;
        //int paperType = (int)enumMaterialRecordClass.MaterialClass.Paper;

        public const int PERINCHTOSCREEN = 10;//1英寸=10屏（相素点）
        public bool IsNewWhirl = false;//自动拼板是否又进行循环拼板
        //		public int BARCODEWIDTH = 30;//条码点25个象素点宽
        public int BARCODEWIDTH2 = 30;//条码点25个象素点宽
        int[] BlackWidth = new Int32[3] { 200, 300, 400 };
        int[] ComboxNum = new Int32[3] { 2, 3, 4 };
        int[] CountLevel = new Int32[3] { 0, 0, 0 };

        int[] BlackWidthLong = new Int32[3] { 10, 15, 20 };
        int[] ComboxNumLong = new Int32[3] { 2, 3, 4 };
        int[] CountLevelLong = new Int32[3] { 0, 0, 0 };
        int changeLevel = 0;
        int tryTime = 0;

        int[] BlackWidthForce = new Int32[3] { 10, 15, 20 };
        int[] ComboxNumForce = new Int32[3] { 2, 3, 4 };
        int[] CountLevelForce = new Int32[3] { 3, 4, 5 };
        int[] BlackWidthLowWaste = new Int32[3] { 3, 8, 15 };
        int[] ComboxNumLowWaste = new Int32[3] { 2, 3, 4 };
        int[] CountLevelLowWaste = new Int32[3] { 3, 4, 5 };
        LayoutDll.ClassInterFace InterFace = new LayoutDll.ClassInterFace();
        public bool IsAutoStop { get; set; }

        public List<PhotoInfo_PinBan> AutoPinSN(IEnumerable<PhotoInfo_PinBan> list, List<Tb_paperTemplate_Info> templateList, Printer_Info CurentPrinter, out decimal outWaste, out int length, int minLength, int level, out Tb_paperTemplate_Info outBoardTemplete)
        {
            List<PhotoInfo_PinBan> rtnList = new List<PhotoInfo_PinBan>();
            List<TempResult> resultList = new List<TempResult>();
            List<PhotoInfo_PinBan> sourcePList = new List<PhotoInfo_PinBan>();
            foreach (PhotoInfo_PinBan item in list)
            {
                if (!item.IsInBoard)
                {
                    sourcePList.Add(item);
                }
            }
            List<PhotoInfo_PinBan> inputPList = new List<PhotoInfo_PinBan>();

            //获取最大的版面
            templateList = templateList.OrderByDescending(p => p.BoardHeight).ToList();//版面从大到小获取
            Tb_paperTemplate_Info firstTemp = templateList.FirstOrDefault();

            inputPList = list.ToList();
            foreach (var photo in inputPList)
            {
                photo.IsInBoard = false;
                photo.IsWhirl = false;
                photo.BarCodeStatus = 0;

            }

            //最大的版面获取到照片
            List<PhotoInfo_PinBan> rtnFrist = AutoPinSN(inputPList, firstTemp, CurentPrinter, out outWaste, out length, minLength, 1);
            TempResult firstR = new TempResult();
            firstR.Length = length;
            firstR.Waste = outWaste;
            firstR.BoardTemplete = firstTemp;
            firstR.PhotoList = rtnFrist;

            resultList.Add(firstR);
            //用最大的版面取得照片集合在剩下的版面中顺序执行
            for (int i = 1; i < templateList.Count; i++)// (Tb_paperTemplate_Info template in templateList)
            {
                Tb_paperTemplate_Info template = templateList[i];
                List<PhotoInfo_PinBan> inPList = new List<PhotoInfo_PinBan>();
                foreach (PhotoInfo_PinBan ppb in rtnFrist)
                {
                    PhotoInfo_PinBan photo = new PhotoInfo_PinBan() { PhotoId = ppb.PhotoId, PaperFaceId = ppb.PaperFaceId, PhotoName = ppb.PhotoName, PixHeight = ppb.PixHeight, PixWidth = ppb.PixWidth };
                    photo.IsInBoard = false;
                    photo.IsWhirl = false;
                    photo.BarCodeStatus = 0;
                    photo.Location = new Point(0, 0);
                    inPList.Add(photo);
                }
                List<PhotoInfo_PinBan> rtn = AutoPinSN(inPList, template, CurentPrinter, out outWaste, out length, minLength, level);
                TempResult tResult = new TempResult();
                tResult.Length = length;
                tResult.Waste = outWaste;
                tResult.BoardTemplete = template;
                tResult.PhotoList = rtn;
                if (length >= template.BoardLength * minLength / 100.0 * CurentPrinter.PDPI)
                {
                    resultList.Add(tResult);
                }
            }

            resultList = resultList.OrderBy(p => p.Waste).ToList();
            if (resultList.Count > 0)
            {
                outWaste = resultList.FirstOrDefault().Waste;
                length = resultList.FirstOrDefault().Length;
                List<PhotoInfo_PinBan> tempList = resultList.FirstOrDefault().PhotoList;
                foreach (PhotoInfo_PinBan pdc in tempList)
                {
                    PhotoInfo_PinBan real = sourcePList.FirstOrDefault(p => p.PhotoId == pdc.PhotoId);
                    real.Location = pdc.Location;
                    real.IsInBoard = pdc.IsInBoard;
                    real.BarCodeStatus = pdc.BarCodeStatus;
                    real.IsWhirl = pdc.IsWhirl;
                    rtnList.Add(real);
                }
                outBoardTemplete = resultList.FirstOrDefault().BoardTemplete;
            }
            else
            {
                outBoardTemplete = templateList.FirstOrDefault();
                outWaste = 0;
                length = 0;
                rtnList = null;
            }

            return rtnList;
            //return AutoPinSN21(inputPList, templateList[0], CurentPrinter, waste, out outWaste, out length, minLength, isForcePrint, level);
        }
        /// <summary>
        /// 全自动拼版
        /// </summary>
        /// <param name="sourcePList"></param>
        /// <param name="template"></param>
        /// <param name="CurentPrinter"></param>
        /// <param name="waste"></param>
        /// <param name="outWaste"></param>
        /// <param name="outCurrLength"></param>
        /// <param name="minLength"></param>
        /// <param name="isForcePrint"></param>
        /// <param name="autoModel"></param>
        /// <returns></returns>
        public List<PhotoInfo_PinBan> AutoPinSN(IEnumerable<PhotoInfo_PinBan> sourcePList, Tb_paperTemplate_Info template, Printer_Info CurentPrinter, out decimal outWaste, out int outCurrLength, int minLength, int autoModel)
        {
            int suitMinX = Convert.ToInt32(0.7 * template.BoardLength * CurentPrinter.PDPI); //打印机最小的出版长度
            ///板宽  
            int boardHeight = Convert.ToInt32(template.BoardHeight * CurentPrinter.PDPI);
            ///版长
            int boardLenght = Convert.ToInt32(template.BoardLength * CurentPrinter.PDPI);
            int MinX = Convert.ToInt32(template.BoardLength * ((float)minLength / 100) * CurentPrinter.PDPI); //打印机最小的出版长度
            Point PLocation = new Point(0, 0); //图片的坐标,以实际的大纸的坐标为准  
            outCurrLength = 0; //记录真实照片长度
            foreach (PhotoInfo_PinBan photo in sourcePList)
            {
                photo.PixFactHeigth = Convert.ToInt32(Convert.ToDecimal(photo.Height * CurentPrinter.PDPI));
                photo.PixFactWidth = Convert.ToInt32(Convert.ToDecimal(photo.Width * CurentPrinter.PDPI));
                photo.IsInBoard = false;
                photo.IsWhirl = false;
            }
            //sourcePList = ColnePhotoList(sourcePList);
            PLocation = new Point(0, 0);
            Size source_Size = new Size(boardLenght, boardHeight);
            List<PhotoInfo_PinBan> resultList = new List<PhotoInfo_PinBan>();
            List<Line> VerticalLine = new List<Line>();///存放拼过的竖线
            List<Point> CurrVLinePhotoPoint = new List<Point>();
            List<MyRectangle> listRect = new List<MyRectangle>();

            Rectangle currRectang = new Rectangle(new Point(0, 0), new Size(boardLenght, boardHeight));//当前矩形框
            int currWidth = 0;//记录当前要补充的块的宽
            int tempHeight = boardHeight;
            int maxWidth = boardLenght;
            int outHeightLeft;
            int outWidthLeft;

            //用户计算回滚操作
            bool CanPut = false;//标志该版可以结束
            //int CanPutNum = 0;//可以出的前几张
            double CanPutWaste = 1;//当前的浪费率rr

            List<int> CutPhotoidList = new List<int>();//将能够出的照片暂存
            Rectangle CutRectangle = new Rectangle();//达到回滚条件时的最小矩形框
            double currWate = 0;
            //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "数据准备成功");
            while (true)
            {

                //try
                //{

                List<PhotoInfo_PinBan> TSPlist;
                try
                {
                    TSPlist = sourcePList.Where(p => p.IsInBoard == false && ((p.PixFactHeigth <= boardHeight && p.PixFactWidth <= boardLenght) || (p.PixFactHeigth <= boardLenght && p.PixFactWidth <= boardHeight))).ToList(); ;
                    if (TSPlist.Count == 0)
                    {
                        CanPutWaste = currWate;
                        CutPhotoidList = new List<int>();
                        foreach (PhotoInfo_PinBan photoct in resultList)
                        {
                            CutPhotoidList.Add(photoct.PhotoId);
                        }
                        break;//直接出因为没有照片了
                    }
                    if (IsAutoStop)
                    {
                        resultList.ForEach(p => p.IsInBoard = false);

                        resultList = new List<PhotoInfo_PinBan>();
                        break;
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("初始化 出错");
                }

                #region//处理照片放置顺序
                int putPhotoOrder = -1;//0照片宽度按照小大排 1照片宽度按照大小排-1初始值
                Point leftTop = currRectang.Location;//左上定点
                Point leftBottom = new Point(currRectang.Location.X, currRectang.Location.Y + currRectang.Height);//坐下顶点
                try
                {
                    if ((leftBottom.Y - leftTop.Y) == boardHeight)
                    {
                        putPhotoOrder = 1;
                    }
                    else
                    {
                        if (leftTop.Y == 0)
                        {
                            putPhotoOrder = 1;
                        }
                        if (leftTop.Y != 0 && leftBottom.Y == boardHeight)
                        {
                            putPhotoOrder = 0;
                        }
                        if (putPhotoOrder == -1)
                        {
                            var topRect1 = listRect.Where(p => p.LeftBottomPoint.X < leftTop.X && p.RightBottomPoint.X >= leftTop.X);
                            MyRectangle topRect = listRect.FirstOrDefault(p => p.LeftBottomPoint.X <= leftTop.X && p.RightBottomPoint.X > leftTop.X && p.LeftBottomPoint.Y == leftTop.Y);
                            MyRectangle bottomRect = listRect.FirstOrDefault(p => p.LeftTopPoint.X <= leftBottom.X && p.RighTopPoint.X > leftBottom.X && p.LeftTopPoint.Y == leftBottom.Y);
                            if (topRect == null || bottomRect == null)
                            {
                                putPhotoOrder = 1;
                            }
                            if (topRect != null && bottomRect != null)
                            {
                                int topLength = topRect.RighTopPoint.X - leftTop.X;
                                int bottomLength = bottomRect.RightBottomPoint.X - leftBottom.X;
                                if (topLength >= bottomLength)
                                {
                                    putPhotoOrder = 0;
                                }
                                else
                                {
                                    putPhotoOrder = 1;
                                }
                            }



                        }

                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("计算顺序出错");
                }
                #endregion

                #region//获取要拼版的照片
                //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "确定照片顺序成功");
                List<PhotoInfo_PinBan> PhotoList = new List<PhotoInfo_PinBan>();
                try
                {

                    PhotoList = FindSuitPhotos(TSPlist, currRectang, PhotoBarCodeStatus.RightOrLeft, out outHeightLeft, sourcePList, putPhotoOrder, template, CurentPrinter, MinX, autoModel, CurrVLinePhotoPoint);

                }
                catch (Exception ex)
                {
                    throw new Exception("取照片出错");
                }
                #endregion


                if (PhotoList == null || PhotoList.Count == 0)
                {
                    // WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "获取不到照片");
                    //try
                    //{
                    #region//找不到合适的照片来放
                    try
                    {
                        if (VerticalLine.Count == 1)
                        {
                            if (CutPhotoidList.Count == 0)
                            {
                                CanPutWaste = currWate;
                                CutPhotoidList = new List<int>();
                                foreach (PhotoInfo_PinBan photoct in resultList)
                                {
                                    CutPhotoidList.Add(photoct.PhotoId);
                                }
                                currRectang.Height = currRectang.Width = 0;
                                break;//直接出因为没有照片了
                            }
                            if (VerticalLine.FirstOrDefault().StartPoint.X >= suitMinX)//已经达到出版最佳尺寸
                            {
                                break;
                            }
                            else//当不够设定的最佳尺寸时
                            {
                                ///1回滚
                                break;
                            }



                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("判断是否结束出错" + ex.InnerException);
                    }


                    //}
                    ///建立剩余空白版就是未找到的那块放入List
                    ///空白块分两种一种是横向一种是竖向实际是检查上下两个方向的x取小的
                    ///块的宽需要计算得出而不是当前操作快的宽度
                    //查找空白框的顶点所在的那个照片块
                    MyRectangle priRect = null;
                    int balckRWidth = 0;

                    //if (VerticalLine == null)
                    //{
                    //    throw new Exception("VerticalLine为空");
                    //}


                    //重新写的填充小块的方法
                    Line firstLine = null;

                    try
                    {
                        firstLine = VerticalLine.OrderBy(p => p.StartPoint, new MyPointComparer()).FirstOrDefault();
                    }
                    catch (Exception ex) { new Exception("获取firstLine出错"); };

                    if (firstLine == null)
                    {
                        if (TSPlist.Count == 0)
                        {
                            break;
                        }
                        // 理论不可以
                        //下一个轮回
                        foreach (var p in sourcePList)
                        {
                            p.IsInBoard = false;
                        }

                        resultList = new List<PhotoInfo_PinBan>();
                        VerticalLine = new List<Line>();
                        listRect = new List<MyRectangle>();
                        currRectang = new Rectangle(new Point(0, 0), new Size(boardLenght, boardHeight));//当前矩形框
                        continue;
                    }


                    Point BlackLocation = firstLine.StartPoint;
                    int BlackH = firstLine.EndPoint.Y - firstLine.StartPoint.Y;
                    int TopLeft = 0, BottomLeft = 0;
                    //查找他的上面的矩形   下边Y值等于Location里的Y, X位于矩形内
                    MyRectangle TopRect = null;
                    try
                    {
                        TopRect = listRect.Where(r => r.PRactangle.Location.Y + r.PRactangle.Height == BlackLocation.Y && BlackLocation.X >= r.PRactangle.Location.X && BlackLocation.X < r.PRactangle.Location.X + r.PRactangle.Width).FirstOrDefault();
                        if (TopRect == null)
                        {
                            TopLeft = -1;//上面没有了
                        }
                        else
                        {
                            TopLeft = TopRect.PRactangle.Location.X + TopRect.PRactangle.Width - BlackLocation.X;
                        }

                        //查找他的下面的矩形   上边Y值等于firstLine终点的Y,   X位于矩形内
                        MyRectangle BottomRect = listRect.Where(r => r.PRactangle.Location.Y == firstLine.EndPoint.Y && firstLine.EndPoint.X >= r.PRactangle.Location.X && firstLine.EndPoint.X < r.PRactangle.Location.X + r.PRactangle.Width).FirstOrDefault();

                        if (BottomRect == null)
                        {
                            BottomLeft = -1;//下面没有了
                        }
                        else
                        {
                            BottomLeft = BottomRect.PRactangle.Location.X + BottomRect.PRactangle.Width - firstLine.EndPoint.X;
                        }
                        //计算要用空白补充的最小单位
                        if (TopLeft == -1 && BottomLeft != -1)
                        {
                            balckRWidth = BottomLeft;
                        }
                        else if (TopLeft != -1 && BottomLeft == -1)
                        {
                            balckRWidth = TopLeft;
                        }
                        else if (TopLeft != -1 && BottomLeft != -1)
                        {
                            if (TopLeft >= BottomLeft)
                            {
                                balckRWidth = BottomLeft;
                            }
                            else
                            {
                                balckRWidth = TopLeft;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("判断空白位置出错" + ex.InnerException.ToString());
                    }

                    try
                    {
                        MyRectangle BlackRect = new MyRectangle(new Rectangle(currRectang.Location, new Size(balckRWidth, currRectang.Size.Height)), BARCODEWIDTH2);
                        BlackRect.isUsefull = false;
                        if (BlackRect.PRactangle.Location.X + BlackRect.PRactangle.Width > maxWidth)
                        {
                            balckRWidth = maxWidth;
                        }
                        listRect.Add(BlackRect);//找不到合适的照片用白板代替应该控制白板的大小
                        //记录当前的竖线集合以便找到下一个矩形框
                        VerticalLine.Remove(VerticalLine.FirstOrDefault(p => p.StartPoint == BlackRect.PRactangle.Location));

                        Point startPoint = new Point(BlackRect.PRactangle.Location.X + BlackRect.PRactangle.Width, BlackRect.PRactangle.Y);
                        Point endPoint = new Point(BlackRect.PRactangle.Location.X + BlackRect.PRactangle.Width, BlackRect.PRactangle.Y + BlackRect.PRactangle.Height);


                        AddLine(ref VerticalLine, new Line(startPoint, endPoint));


                        //}

                        //将继续找下一个可以填充的块如果找不到情况重试
                        //获取最小的位置值XY 都是最小的
                        firstLine = VerticalLine.OrderBy(p => p.StartPoint, new MyPointComparer()).FirstOrDefault();
                        int minX = firstLine.StartPoint.X;
                        if (minX == 11998)
                        {

                        }
                        int minY = firstLine.StartPoint.Y;
                        if (firstLine.EndPoint.Y > boardHeight)
                        {

                        }
                        CurrVLinePhotoPoint = GetFocusPoint(listRect, firstLine);
                        int Height = firstLine.EndPoint.Y - firstLine.StartPoint.Y;//下个矩形的高等于线的高度
                        int Width = boardLenght - minX;//下个矩形的长度等于版长减去minx定点的横坐标
                        currWidth = currRectang.Width;
                        Rectangle newrang = new Rectangle(new Point(minX, minY), new Size(Width, Height));

                        currRectang = newrang;
                        continue;//继续填充
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("计算下一个矩形出错");
                    }

                    //}
                    #endregion
                    //}
                    //catch (Exception ex)
                    //{
                    //    throw new Exception("补空白出错" +ex.InnerException);
                    //}
                }
                else
                {
                    //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "获取到第一组照片");

                    if (listRect.Count == 0)//第一张照片
                    {
                        try
                        {
                            #region//第一张照片
                            // FristSize=PhotoList.FirstOrDefault().PSize;
                            MyRectangle photoRect = null;
                            CanPut = false;
                            bool isFirstPhoto = true;
                            int MaxWidth = 0;
                            foreach (PhotoInfo_PinBan photo in PhotoList)
                            {
                                MyRectangle myr = new MyRectangle(photo, BARCODEWIDTH2);
                                myr.isUsefull = true;
                                listRect.Add(myr);
                                photo.IsInBoard = true;

                                //AddInBoardNum(sourcePList ,photo.OrderProductId);

                                resultList.Add(photo);
                                photoRect = myr;
                                //photo.TryTime++;
                                ////标记照片已经拼版了包含了副本
                                sourcePList.Where(xp => xp.PhotoId == photo.PhotoId).ToList().ForEach(p => p.IsInBoard = true);
                                //if (isFirstPhoto)
                                //{
                                //    photo.TryTime++;
                                //    isFirstPhoto = false;
                                //}

                                #region///验证用

                                #endregion
                                ////VerticalLine.Remove(VerticalLine.FirstOrDefault(p => p.StartPoint == currRectang.Location));

                                outCurrLength = myr.PRactangle.Location.X + myr.PRactangle.Width;//计算当前最长的数字
                                if (MaxWidth < outCurrLength)
                                {
                                    MaxWidth = outCurrLength;
                                }
                                Line delLine = VerticalLine.FirstOrDefault(p => p.StartPoint == myr.PRactangle.Location);
                                Point delStartPoint = new Point(0, 0);
                                Point delEndPoint = new Point(0, currRectang.Height);
                                if (delLine == null)
                                {

                                }
                                else
                                {
                                    delStartPoint = new Point(delLine.StartPoint.X, delLine.StartPoint.Y);
                                    delEndPoint = new Point(delLine.EndPoint.X, delLine.EndPoint.Y);
                                }
                                VerticalLine.Remove(delLine);//移除原先的线          
                                AddLine(ref VerticalLine, new Line(new Point(myr.PRactangle.X + myr.PRactangle.Width, myr.PRactangle.Y), new Point(myr.PRactangle.X + myr.PRactangle.Width, myr.PRactangle.Y + myr.PRactangle.Height)));
                                // VerticalLine.Add();
                                AddLine(ref VerticalLine, new Line(new Point(delStartPoint.X, myr.PRactangle.Y + myr.PRactangle.Height), new Point(myr.PRactangle.X, delEndPoint.Y)));
                                //VerticalLine.Add();
                                //outCurrLength = VerticalLine.Max(p => p.StartPoint.X);
                            }




                            Line firstLine = VerticalLine.OrderBy(p => p.StartPoint, new MyPointComparer()).FirstOrDefault();
                            if (firstLine.EndPoint.Y > boardHeight)
                            {

                            }
                            CurrVLinePhotoPoint = GetFocusPoint(listRect, firstLine);
                            int minX = firstLine.StartPoint.X;
                            int minY = firstLine.StartPoint.Y;
                            int Height = firstLine.EndPoint.Y - firstLine.StartPoint.Y;//下个矩形的高等于线的高度
                            int Width = boardLenght - minX;//下个矩形的长度等于版长减去minx定点的横坐标
                            currWidth = currRectang.Width;
                            Rectangle newrang = new Rectangle(new Point(minX, minY), new Size(Width, Height));
                            currRectang = newrang;
                            currWate = CheckWaste(listRect, boardHeight);
                            if (CanPutWaste >= currWate && outCurrLength >= MinX)
                            {
                                CanPutWaste = currWate;
                                CutPhotoidList = new List<int>();
                                foreach (PhotoInfo_PinBan photoct in resultList)
                                {
                                    CutPhotoidList.Add(photoct.PhotoId);
                                }
                                MyRectangle topRect = listRect.Where(r => r.PRactangle.Y + r.PRactangle.Height == firstLine.StartPoint.Y && firstLine.StartPoint.X >= r.PRactangle.X && firstLine.StartPoint.X <= r.PRactangle.X + r.PRactangle.Width).OrderByDescending(o => o.PRactangle.X + o.PRactangle.Width).FirstOrDefault();
                                MyRectangle bottomRect = listRect.Where(r => r.PRactangle.Y == firstLine.EndPoint.Y && firstLine.EndPoint.X >= r.PRactangle.X && firstLine.EndPoint.X <= r.PRactangle.X + r.PRactangle.Width).OrderByDescending(o => o.PRactangle.X + o.PRactangle.Width).FirstOrDefault(); ;

                                if (topRect != null && bottomRect != null)
                                {
                                    int topL = topRect.PRactangle.X + topRect.PRactangle.Width - firstLine.StartPoint.X;
                                    int bottomL = bottomRect.PRactangle.X + bottomRect.PRactangle.Width - firstLine.StartPoint.X;
                                    if (topL >= bottomL)
                                    {
                                        CutRectangle = new Rectangle(new Point(minX, minY), new Size(topL, Height));

                                    }
                                    else
                                    {
                                        CutRectangle = new Rectangle(new Point(minX, minY), new Size(bottomL, Height));
                                    }
                                }
                                else if (topRect == null && bottomRect != null)
                                {
                                    int bottomL = bottomRect.PRactangle.X + bottomRect.PRactangle.Width - firstLine.StartPoint.X;
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(bottomL, Height));
                                }
                                else if (topRect != null && bottomRect == null)
                                {
                                    int topL = topRect.PRactangle.X + topRect.PRactangle.Width - firstLine.StartPoint.X;
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(topL, Height));
                                }
                                else
                                {
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(0, 0));
                                }
                            }
                            continue;//继续填充


                            #endregion
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("放第一批照片出错" + ex.StackTrace);
                        }
                    }
                    else
                    {
                        //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "获取到版上非第一组照片照片");

                        try
                        {
                            #region//将照片放到找到的合适的版上
                            int tHeight = 0;
                            //MyRectangle lastRang = null;
                            ///把照片放入找到的暂存块
                            MyRectangle photoRect = null;
                            foreach (PhotoInfo_PinBan photo in PhotoList)
                            {
                                MyRectangle myr = new MyRectangle(photo, BARCODEWIDTH2);
                                myr.isUsefull = true;
                                listRect.Add(myr);//加入暂存块
                                //photo.IsInBoard = true;
                                resultList.Add(photo);//加入结果列表
                                //lastRang = myr;
                                photoRect = myr;
                                //标记照片已经拼版了包含了副本
                                sourcePList.Where(xp => xp.PhotoId == photo.PhotoId).ToList().ForEach(p => p.IsInBoard = true);
                                //tempHeight+=myr.PRactangle.Height;


                                //实际照片块


                                var templist = VerticalLine.Where(p => p.StartPoint.X == myr.PRactangle.Location.X && p.StartPoint.Y <= myr.PRactangle.Location.Y && p.EndPoint.Y >= myr.PRactangle.Location.Y);
                                if (templist.Count() == 0)
                                {

                                }
                                Line delLine = templist.FirstOrDefault();
                                if (delLine.StartPoint.Y == myr.PRactangle.Y)
                                {
                                    if (delLine == null)
                                    {
                                    }
                                    Line newLine = new Line(new Point(myr.PRactangle.Location.X, myr.PRactangle.Location.Y), new Point(myr.PRactangle.Location.X, myr.PRactangle.Location.Y + myr.PRactangle.Height));//照片所在左边的
                                    if (newLine == null)
                                    {

                                    }
                                    List<Line> lines = delLine.SubtractLine(newLine);
                                    if (lines.Count > 1)
                                    {

                                    }
                                    Point delStartPoint = new Point(delLine.StartPoint.X, delLine.StartPoint.Y);
                                    Point delEndPoint = new Point(delLine.EndPoint.X, delLine.EndPoint.Y);
                                    VerticalLine.Remove(delLine);//移除原先的线                      
                                    AddLine(ref VerticalLine, new Line(new Point(myr.PRactangle.Location.X + myr.PRactangle.Width, myr.PRactangle.Location.Y), new Point(myr.PRactangle.Location.X + myr.PRactangle.Width, myr.PRactangle.Location.Y + myr.PRactangle.Height)));//画照片右边的线

                                    //AddLine(ref VerticalLine, new Line(new Point(myr.PRactangle.Location.X, myr.PRactangle.Location.Y + myr.PRactangle.Height), new Point(delEndPoint.X, delEndPoint.Y)));//画照片下面左边的线
                                    foreach (Line l in lines)
                                    {
                                        AddLine(ref VerticalLine, l);
                                    }
                                }
                                else
                                {
                                    VerticalLine.Remove(delLine);//移除原先的线 
                                    AddLine(ref VerticalLine, new Line(new Point(delLine.StartPoint.X, delLine.StartPoint.Y), new Point(myr.PRactangle.X, myr.PRactangle.Y)));
                                    AddLine(ref VerticalLine, new Line(new Point(delLine.StartPoint.X + myr.PRactangle.Width, myr.PRactangle.Y), new Point(delLine.StartPoint.X + myr.PRactangle.Width, myr.PRactangle.Y + myr.PRactangle.Height)));
                                    AddLine(ref VerticalLine, new Line(new Point(myr.PRactangle.X, myr.PRactangle.Y + myr.PRactangle.Height), new Point(delLine.EndPoint.X, delLine.EndPoint.Y)));

                                }

                                //List<Line> lines=
                            }
                            Line lengthL = VerticalLine.OrderByDescending(p => p.StartPoint, new MyPointComparer()).FirstOrDefault();
                            outCurrLength = lengthL.StartPoint.X;




                            //记录当前的竖线集合以便找到下一个矩形框
                            //获取最小的位置值XY 都是最小的
                            Line firstLine = VerticalLine.OrderBy(p => p.StartPoint, new MyPointComparer()).FirstOrDefault();
                            if (firstLine.EndPoint.Y > boardHeight)
                            {

                            }

                            CurrVLinePhotoPoint = GetFocusPoint(listRect, firstLine);

                            int minX = firstLine.StartPoint.X;
                            int minY = firstLine.StartPoint.Y;
                            int Height = firstLine.EndPoint.Y - firstLine.StartPoint.Y;//下个矩形的高等于线的高度
                            int Width = boardLenght - minX;//下个矩形的长度等于版长减去minx定点的横坐标
                            currWidth = currRectang.Width;
                            Rectangle newrang = new Rectangle(new Point(minX, minY), new Size(Width, Height));

                            currRectang = newrang;

                            ///当前放进去的浪费率
                            currWate = CheckWaste(listRect, boardHeight);
                            if (CanPutWaste >= currWate && outCurrLength >= MinX)
                            {
                                CanPutWaste = currWate;
                                CutPhotoidList = new List<int>();
                                foreach (PhotoInfo_PinBan photoct in resultList)
                                {
                                    CutPhotoidList.Add(photoct.PhotoId);
                                }
                                MyRectangle topRect = listRect.Where(r => r.PRactangle.Y + r.PRactangle.Height == firstLine.StartPoint.Y && firstLine.StartPoint.X >= r.PRactangle.X && firstLine.StartPoint.X <= r.PRactangle.X + r.PRactangle.Width).OrderByDescending(o => o.PRactangle.X + o.PRactangle.Width).FirstOrDefault();
                                MyRectangle bottomRect = listRect.Where(r => r.PRactangle.Y == firstLine.EndPoint.Y && firstLine.EndPoint.X >= r.PRactangle.X && firstLine.EndPoint.X <= r.PRactangle.X + r.PRactangle.Width).OrderByDescending(o => o.PRactangle.X + o.PRactangle.Width).FirstOrDefault(); ;

                                if (topRect != null && bottomRect != null)
                                {
                                    int topL = topRect.PRactangle.X + topRect.PRactangle.Width - firstLine.StartPoint.X;
                                    int bottomL = bottomRect.PRactangle.X + bottomRect.PRactangle.Width - firstLine.StartPoint.X;
                                    if (topL >= bottomL)
                                    {
                                        CutRectangle = new Rectangle(new Point(minX, minY), new Size(topL, Height));

                                    }
                                    else
                                    {
                                        CutRectangle = new Rectangle(new Point(minX, minY), new Size(bottomL, Height));
                                    }
                                }
                                else if (topRect == null && bottomRect != null)
                                {
                                    int bottomL = bottomRect.PRactangle.X + bottomRect.PRactangle.Width - firstLine.StartPoint.X;
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(bottomL, Height));
                                }
                                else if (topRect != null && bottomRect == null)
                                {
                                    int topL = topRect.PRactangle.X + topRect.PRactangle.Width - firstLine.StartPoint.X;
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(topL, Height));
                                }
                                else
                                {
                                    CutRectangle = new Rectangle(new Point(minX, minY), new Size(0, 0));
                                }


                            }
                            continue;//继续填充
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("放置照片出错" + ex.StackTrace);
                        }

                            #endregion

                    }
                }

                //}
                //catch (Exception ex)
                //{
                //    throw new Exception("计算出错1");
                //}

            }

            if (currWate < 0)
            {
                currWate = 0.001;
            }

            outWaste = (decimal)currWate;

            List<PhotoInfo_PinBan> rtnList = new List<PhotoInfo_PinBan>();
            // WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "获取照片完毕");

            try
            {
                ///回滚获取照片列表
                int iCount = 0;
                //CutPhotoidList = new List<int>();
                foreach (PhotoInfo_PinBan photo in resultList)
                {
                    if (CutPhotoidList.Contains(photo.PhotoId))
                    {

                        rtnList.Add(photo);
                        photo.IsInBoard = true;
                    }
                    else
                    {
                        photo.IsInBoard = false;
                        //photo.TryTime = 0;
                        //SubtractInBoardNum(sourcePList, photo.OrderProductId);
                    }
                    iCount++;
                }
                //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "正在回滚");

                //回滚结束后 填补回滚块
                List<PhotoInfo_PinBan> PhotoBackList = new List<PhotoInfo_PinBan>();
                int leftLength = 0;
                if (CutRectangle.Width != 0 || CutRectangle.Height != 0)
                {
                    PhotoBackList = FindSuitPhotos(sourcePList.Where(p => p.IsInBoard == false).ToList(), CutRectangle, PhotoBarCodeStatus.RightOrLeft, out leftLength, sourcePList, 0, template, CurentPrinter, MinX, 0, CurrVLinePhotoPoint);
                }
                if (PhotoBackList != null && PhotoBackList.Count != 0)
                {
                    foreach (PhotoInfo_PinBan photo in PhotoBackList)
                    {
                        photo.IsInBoard = true;
                        rtnList.Add(photo);
                    }
                }

                ///计算版长
                if (rtnList.Count > 0)
                {
                    outCurrLength = rtnList.Max(p => p.Location.X + (p.IsWhirl ? p.PixFactHeigth : p.PixFactWidth) + ((p.BarCodeStatus == (int)PhotoBarCodeStatus.RightOrLeft) ? BARCODEWIDTH2 : 0));
                }
                ///计算浪费率
                decimal photoAreas = 0;
                foreach (PhotoInfo_PinBan photo in rtnList)
                {
                    if (photo.IsWhirl)
                    {
                        if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.RightOrLeft)
                        {

                            photoAreas += (photo.PixFactWidth) * (photo.PixFactHeigth + BARCODEWIDTH2);
                        }
                        else if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom)
                        {
                            photoAreas += (photo.PixFactWidth + BARCODEWIDTH2) * photo.PixFactHeigth;
                        }
                        else
                        {
                            photoAreas += (photo.PixFactWidth) * (photo.PixFactHeigth);
                        }
                    }
                    else
                    {
                        if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.RightOrLeft)
                        {
                            photoAreas += (photo.PixFactWidth + BARCODEWIDTH2) * photo.PixFactHeigth;
                        }
                        else if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom)
                        {
                            photoAreas += (photo.PixFactWidth) * (photo.PixFactHeigth + BARCODEWIDTH2);
                        }
                        else
                        {
                            photoAreas += (photo.PixFactWidth) * (photo.PixFactHeigth);
                        }
                    }

                }
                if (outCurrLength != 0)
                {
                    outWaste = 1 - photoAreas / ((decimal)outCurrLength * boardHeight);
                }
                else
                {
                    outWaste = 0;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("计算出错2");
            }


            //int maxY = rtnList.Max(p => p.Location.Y + (p.IsWhirl ? p.PixFactWidth : p.PixFactHeigth));
            //int maxy2 = rtnList.Max(p => p.Location.Y + (p.IsWhirl ? Convert.ToInt32(((double)p.PixWidth) / p.DPI * CurentPrinter.PDPI) : Convert.ToInt32(((double)p.PixHeight) / p.DPI * CurentPrinter.PDPI)));
            return rtnList;
        }
        ///// <summary>
        // 获取一组照片
        // </summary>
        // <param name="inList">可用照片列表</param>
        // <param name="currRang">当前填充矩形框</param>
        // <param name="barCodeStatus">条码放置方向</param>
        // <param name="LeftH">剩余高度</param>
        // <param name="AllList"></param>
        // <param name="putPhotoOrder">照片放置宽度顺序</param>
        // <param name="template">当前模板</param>
        // <param name="CurentPrinter">当前打印机</param>
        // <param name="MinLength">最小版长</param>
        // <param name="autoModel">拼版模式</param>
        // /// <param name="inVPoint">当前竖线上的照片点</param>
        // <returns></returns>
        List<PhotoInfo_PinBan> FindSuitPhotos(List<PhotoInfo_PinBan> inList, Rectangle currRang, PhotoBarCodeStatus barCodeStatus, out int LeftH, IEnumerable<PhotoInfo_PinBan> AllList, int putPhotoOrder, Tb_paperTemplate_Info template, Printer_Info CurentPrinter, int MinLength, int aotuModel, List<Point> inVPoint)
        {

            int inHeigth = currRang.Height; int MaxWidth = currRang.Width;
            //var TEMP = inList.Where(g => g.PixFactWidth <= MaxWidth);
            //var TEMP1 inList= .Where(g => g.PixFactHeigth <= inHeigth);
            //var TEMP2 = inList.Where(g => g.PixFactWidth <= MaxWidth && g.PixFactHeigth <= inHeigth).OrderBy(or => or.PixFactHeigth);
            var photoSizeGroup = inList.Where(g => (g.PixFactWidth <= MaxWidth && g.PixFactHeigth <= inHeigth) || (g.PixFactWidth <= inHeigth && g.PixFactHeigth <= MaxWidth)).OrderByDescending(or => or.PixFactHeigth).GroupBy(p => p.PhotoSizePix).ToList();
            if (photoSizeGroup.Count() == 0)
            {
                LeftH = currRang.Height;
                return null;
            }
            photoSizeGroup = photoSizeGroup.OrderByDescending(or => or.FirstOrDefault().PixFactHeigth).ToList();

            int sizeCount = photoSizeGroup.Count();
            iMageInfo[] sizeArray = new iMageInfo[sizeCount + 1];
            for (int i = 1; i <= sizeCount; i++)
            {
                iMageInfo sizeG = new iMageInfo();
                sizeG.Width = photoSizeGroup[i - 1].FirstOrDefault().PixFactWidth;
                sizeG.Height = photoSizeGroup[i - 1].FirstOrDefault().PixFactHeigth;
                sizeG.Count = photoSizeGroup[i - 1].Count();

                sizeArray[i] = sizeG;
            }
            int[] UseBlackWidth = new int[3];
            int[] UseComboxNum = new int[3];
            int[] UseCountLevel = new int[3];
            if (aotuModel == 0)
            {
                UseBlackWidth = BlackWidthLong;
                UseComboxNum = ComboxNumLong;
                UseCountLevel = CountLevelLong;
            }
            else if (aotuModel == 1)
            {
                UseBlackWidth = BlackWidthLowWaste;
                UseComboxNum = BlackWidthLowWaste;
                UseCountLevel = BlackWidthLowWaste;
            }
            else
            {
                UseBlackWidth = BlackWidthLong;
                UseComboxNum = ComboxNumLong;
                UseCountLevel = CountLevelLong;
            }
            //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "源有"+sizeArray+"组照片");
            //foreach (var aa in sizeArray)
            //{
            //    int bb = 1;
            //    WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "aa=" + " " + aa.Width + " " + aa.Height + " " );
            //    bb++;
            //}
            Array array = sizeArray;
            //第一个参数 数组，第二个第三个 是宽高第四个是条码宽第五个是 容错宽 第六个是组合数 第7个一次取最多尺寸数
            Array sizeResult = null;
            int barcodeWidth = BARCODEWIDTH2;
            //if (barCodeStatus == PhotoBarCodeStatus.NoBarCode)
            //{
            //    barcodeWidth = 0;
            //}
            int tempLevel = changeLevel;
        leableA:
            try
            {
                int currBlank = Convert.ToInt32(((float)UseBlackWidth[tempLevel] * 7620 / (template.BoardHeight * CurentPrinter.PDPI) / 100) * inHeigth);
                if (currBlank > 1500)
                {
                    currBlank = 1500;
                }
                //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + tempLevel);
                //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + MaxWidth + "|" + inHeigth + "|" + barcodeWidth + "|" + currBlank + "|" + UseComboxNum[tempLevel] + "|" + UseCountLevel[tempLevel]);

                sizeResult = InterFace.Function3(ref array, MaxWidth, inHeigth, barcodeWidth, currBlank, UseComboxNum[tempLevel], UseCountLevel[tempLevel]);//
            }
            catch (Exception ex)
            {
                // WriteLogForCheck.WriteLogFile(DateTime.Now + ":调用Function3出错" + ex.Message);

                throw ex;
            }
            if (sizeResult.Length == 0)
            {
                throw new Exception("请确认已装入加密狗后再试");
            }



            iMageInfo[] arrResult = (iMageInfo[])sizeResult;
            //foreach (var aa in arrResult)
            //{
            //    int bb = 1;
            //    WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "aa=" + " " + aa.Width + " " + aa.Height + " ");
            //    bb++;
            //}

            //此处为处理找不到片子时放宽Level
            if (arrResult[0].Count == 0)
            {
                if (tempLevel >= 2)
                {
                    // WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "tempLevel=" + tempLevel);

                    LeftH = 0;
                    return new List<PhotoInfo_PinBan>();
                }
                else
                {
                    tempLevel++;
                    goto leableA;
                }


            }

            //此处判断小片

            int maxphotoWidth = arrResult.Max(p => p.Width);
            int maxphotoHeight = arrResult.Max(p => p.Height);
            //decimal colphotoNum = (decimal)template.Height / template.MinPhotoSize;
            if ((maxphotoWidth <= template.MinPhotoSize * CurentPrinter.PDPI && maxphotoHeight < template.MinPhotoSize * CurentPrinter.PDPI) && currRang.Height >= template.BoardHeight * CurentPrinter.PDPI * 0.5)
            {
                if (tempLevel < 2)
                {
                    tempLevel++;
                    goto leableA;
                }
                else
                {

                    if (currRang.Height >= template.BoardHeight * CurentPrinter.PDPI * 0.5 && currRang.X >= MinLength)
                    {
                        int testoutHeightLeft = 0;
                        List<PhotoInfo_PinBan> Templist = AllList.Where(p => p.IsInBoard == false && ((p.PixFactHeigth <= template.BoardHeight * CurentPrinter.PDPI && p.PixFactWidth <= template.BoardLength * CurentPrinter.PDPI) || (p.PixFactHeigth <= template.BoardLength * CurentPrinter.PDPI && p.PixFactWidth <= template.BoardHeight * CurentPrinter.PDPI))).ToList(); ;

                        List<PhotoInfo_PinBan> PhotoTestList = FindSuitPhotosSmall(Templist, new Rectangle(new Point(0, 0), new Size((int)template.BoardLength * CurentPrinter.PDPI, (int)template.BoardHeight * CurentPrinter.PDPI)), PhotoBarCodeStatus.RightOrLeft, out testoutHeightLeft, 0);

                        double maxphotoWidthTest = PhotoTestList.Max(p => p.Width);
                        double maxphotoHeightTest = PhotoTestList.Max(p => p.Height);
                        if (maxphotoWidthTest <= (double)template.MinPhotoSize && maxphotoWidthTest < (double)template.MinPhotoSize)
                        {
                            //不处理放进版面
                        }
                        else
                        {
                            //认为次情况不能取到照片
                            LeftH = 0;
                            return new List<PhotoInfo_PinBan>();
                        }

                    }
                    else
                    {
                        //不处理放进版面
                    }
                }



            }

            string Key = "";
            Dictionary<string, int> sizePair = new Dictionary<string, int>();
            List<PhotoInfo_PinBan> suitest = new List<PhotoInfo_PinBan>();

            //WriteLogForCheck.WriteLogFile(DateTime.Now + ":" + "suites.count=" + suitest.Count);


            Dictionary<int, int> orderAndNum = new Dictionary<int, int>();//orderid和缺少多少张就完成
            List<int> AddedPhotoidlist = new List<int>();
            for (int i = 0; i < arrResult.Length; i++)
            {
                List<PhotoInfo_PinBan> suitTemp = new List<PhotoInfo_PinBan>();
                var a = inList.Where(p => p.PixFactWidth == arrResult[i].Width && p.PixFactHeigth == arrResult[i].Height);
                var b = a.OrderByDescending(or => or.Priority);
                int icount = 0;
                foreach (var ph in b)
                {
                    if (AddedPhotoidlist.Contains(ph.PhotoId))
                    {
                        continue;
                    }
                    else
                    {
                        AddedPhotoidlist.Add(ph.PhotoId);
                        suitTemp.Add(ph);
                        icount++;
                        if (icount == arrResult[i].Count)
                        {
                            break;
                        }
                    }
                }
                //处理条码
                if (barCodeStatus != PhotoBarCodeStatus.NoBarCode)
                {
                    if (arrResult[i].barCode == 0)
                    {
                        suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.RightOrLeft);

                    }
                    else
                    {
                        suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.TopOrBottom);
                    }
                }
                else
                {
                    suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.NoBarCode);
                }
                //处理旋转
                if (arrResult[i].isRotate == 1)
                {
                    suitTemp.ForEach(en => en.IsWhirl = true);
                }
                else
                {
                    suitTemp.ForEach(en => en.IsWhirl = false);
                }
                suitest.AddRange(suitTemp);



            }

            //新的获取照片顺序的按照剩余照片最少的 产品的原则获取照片



            //确定照片的摆放顺序
            //Point leftTop = currRang.Location;//左上定点
            //Point leftBottom = new Point(currRang.Location.X, currRang.Location.Y + currRang.Height);//坐下顶点



            //suitest.Add(photoSizeGroup.FirstOrDefault());
            //suitest = suitest.OrderByDescending(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            if (putPhotoOrder == 0)
            {
                suitest = suitest.OrderBy(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            }
            else
            {
                suitest = suitest.OrderByDescending(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            }
            int col = 0;
            int CurrHeight = currRang.Location.Y; ;

            foreach (var photo in suitest)
            {

                //计算合适的 照片的坐标
                if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom)
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth + BARCODEWIDTH2;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth + BARCODEWIDTH2;
                    }

                }
                else if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.RightOrLeft)
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth;
                    }
                }
                else
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth;
                    }
                }
                //if (photo.Location.X == 0 && photo.Location.Y == 0)
                //{

                //}

            }
            int newCurrHeight = suitest.Max(p => p.Location.Y + (p.IsWhirl != true ? p.PixFactHeigth : p.PixFactWidth) + (p.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom ? BARCODEWIDTH2 : 0));
            //LeftH = inHeigth - CurrHeight + currRang.Location.Y;//还差多少可以填满
            if (newCurrHeight != CurrHeight)
            {

            }
            LeftH = inHeigth - newCurrHeight + currRang.Location.Y;
            if (LeftH <= 0)
            {

            }
            else
            {

                if (inVPoint.Count > 0)
                {
                    Point FirstPoint = inVPoint.Where(p => p.Y >= currRang.Y).OrderBy(or => or.Y).FirstOrDefault();
                    Point LastPoint = inVPoint.Where(p => p.Y <= currRang.Y + currRang.Height).OrderByDescending(or => or.Y).FirstOrDefault();
                    int topHeight = FirstPoint.Y - currRang.Y;
                    if (FirstPoint.Y < currRang.Location.Y)
                    {

                    }
                    else
                    {
                        int bottomHeight = currRang.Y + currRang.Height - LastPoint.Y;
                        if (LeftH < topHeight && LeftH < bottomHeight)
                        {
                            //移动不起作用
                        }
                        else if (LeftH <= topHeight && LeftH >= bottomHeight)
                        {
                            //不动默认往上放 但是照片要往下移动的距离靠近缝隙
                            foreach (var photo in suitest)
                            {
                                photo.Location = new Point(photo.Location.X, photo.Location.Y + (LeftH - bottomHeight));

                            }

                        }
                        else if (LeftH >= topHeight && LeftH <= bottomHeight)
                        {
                            //不动默认往上放 但是照片要往下移动的距离靠近缝隙
                            foreach (var photo in suitest)
                            {
                                photo.Location = new Point(photo.Location.X, photo.Location.Y + topHeight);

                            }
                        }
                        else if (LeftH > topHeight && LeftH > bottomHeight)
                        {
                            if (topHeight < bottomHeight)
                            {
                                //不动默认往上放 但是照片要往下移动的距离靠近缝隙
                                foreach (var photo in suitest)
                                {
                                    photo.Location = new Point(photo.Location.X, photo.Location.Y + topHeight);

                                }
                            }
                            else
                            {
                                //不动默认往上放 但是照片要往下移动=的距离靠近缝隙
                                foreach (var photo in suitest)
                                {
                                    photo.Location = new Point(photo.Location.X, photo.Location.Y + (LeftH - bottomHeight));

                                }
                            }
                        }
                    }



                }

                int afterBottomHeight = suitest.Max(p => p.Location.Y + (p.IsWhirl != true ? p.PixFactHeigth : p.PixFactWidth) + (p.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom ? BARCODEWIDTH2 : 0));
                if (afterBottomHeight > currRang.Y + currRang.Height)
                {

                }
                int aftertopHeight = suitest.Min(p => p.Location.Y);
                if (afterBottomHeight < currRang.Y)
                {

                }

            }
            return suitest;

        }
        public class MyPointComparer : IComparer<Point>
        {
            public int Compare(Point x, Point y)
            {
                if (x.X < y.X)
                {
                    return -1;
                }
                else if (x.X == y.X)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
        }

        void CheckLine(ref List<Line> inList, Point startPoint, Point endPoint)
        {
            Line s = inList.FirstOrDefault(p => p.StartPoint == endPoint);//
            if (s != null)
            {
                s.StartPoint = new Point(startPoint.X, startPoint.Y);
            }

            Line e = inList.FirstOrDefault(p => p.EndPoint == startPoint);
            if (e != null)
            {
                e.EndPoint = new Point(endPoint.X, endPoint.Y);
            }

        }
        void AddLine(ref List<Line> inList, Line inAddLine)
        {
            if (inAddLine.StartPoint == inAddLine.EndPoint)
            {
                return;
            }

            Point endPoint = inAddLine.EndPoint;
            Point startPoint = inAddLine.StartPoint;
            if (inList.FirstOrDefault(p => p.StartPoint == startPoint && p.EndPoint == startPoint) != null)
            {
                return;
            }

            Line lineEx = inList.FirstOrDefault(p => (p.StartPoint.X == endPoint.X && p.StartPoint.Y == endPoint.Y) || (p.EndPoint.X == startPoint.X && p.EndPoint.Y == startPoint.Y));//判断是否有现有在一条先上的两条线

            if (lineEx != null)//合并两个在一条直线上的先
            {

                if (lineEx.StartPoint == inAddLine.EndPoint)
                {
                    lineEx.StartPoint = inAddLine.StartPoint;
                }
                if (lineEx.EndPoint == inAddLine.StartPoint)
                {
                    lineEx.EndPoint = inAddLine.EndPoint;
                }

            }
            else
            {

                ////原先
                inList.Add(new Line(startPoint, endPoint));//

            }

        }
        List<Point> GetFocusPoint(List<MyRectangle> listRect, Line inLine)
        {
            List<MyRectangle> photoRLLeft = listRect.Where(p => (p.PRactangle.X + p.PRactangle.Width == inLine.StartPoint.X) && p.isUsefull).ToList();//线左侧的矩形
            List<MyRectangle> photoRLRight = listRect.Where(p => (p.PRactangle.X == inLine.StartPoint.X) && p.isUsefull).ToList();//线右侧的矩形

            //photoRL.ForEach(CurrVLinePhotoPoint.Add());
            List<Point> RtnPoint = new List<Point>();
            foreach (MyRectangle rect in photoRLLeft)//
            {
                //线左侧的矩形要加2个 点右上和右下 并且要判断点是否在线的Y范围内
                if (rect.PRactangle.Y >= inLine.StartPoint.Y && rect.PRactangle.Y <= inLine.EndPoint.Y)
                {
                    Point pointAdd = new Point(rect.PRactangle.X + rect.PRactangle.Width, rect.PRactangle.Y);
                    if (RtnPoint.Where(p => p.X == pointAdd.X && p.Y == pointAdd.Y).ToList().Count == 0)
                    {

                        RtnPoint.Add(pointAdd);
                    }

                }

                if (rect.PRactangle.Y + rect.PRactangle.Height <= inLine.EndPoint.Y && rect.PRactangle.Y + rect.PRactangle.Height >= inLine.StartPoint.Y)
                {
                    Point pointAdd = new Point(rect.PRactangle.X + rect.PRactangle.Width, rect.PRactangle.Y + rect.PRactangle.Height);
                    if (RtnPoint.Where(p => p.X == pointAdd.X && p.Y == pointAdd.Y).ToList().Count == 0)
                    {
                        RtnPoint.Add(pointAdd);
                    }
                }
                //CurrVLinePhotoPoint.Add(new Point(firstLine.StartPoint.X,rect.PRactangle.Y);

            }

            foreach (MyRectangle rect in photoRLRight)
            {
                //线右侧的点要加2个 左上和左下
                if (rect.PRactangle.Y >= inLine.StartPoint.Y)
                {
                    RtnPoint.Add(new Point(rect.PRactangle.X, rect.PRactangle.Y));
                }

                if (rect.PRactangle.Y + rect.PRactangle.Height <= inLine.EndPoint.Y)
                {
                    RtnPoint.Add(new Point(rect.PRactangle.X, rect.PRactangle.Y + rect.PRactangle.Height));
                }

            }
            return RtnPoint;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="inList"></param>
        /// <param name="inMinX"></param>
        /// <param name="inWaste"></param>
        /// <returns></returns>
        bool CheckWasteAndLength(List<MyRectangle> inList, int inMinX, double inWaste, int boardHeight, out double currWaste)
        {
            if (inList == null || inList.Count == 0)
            {
                currWaste = 0;
                return false;
            }
            //double ALLAreas = inList.Sum(p => p.Areas);
            double UsefulAreas = inList.Where(w => w.isUsefull).Sum(p => p.Areas);
            int max = inList.Max(p => p.PRactangle.Location.X + p.PRactangle.Width);
            double ALLAreas = boardHeight * max;
            currWaste = 1 - UsefulAreas / ALLAreas;
            if ((currWaste <= inWaste) && max >= inMinX)
            {

                return true;

            }
            else
            {
                return false;
            }
        }
        bool CheckWaste(List<MyRectangle> inList, double inWaste, int boardHeight, out double outWaste)
        {
            if (inList == null || inList.Count == 0)
            {
                outWaste = 0;
                return false;
            }
            //double ALLAreas = inList.Sum(p => p.Areas);
            double UsefulAreas = inList.Where(w => w.isUsefull).Sum(p => p.Areas);
            //double UsefulAll = inList.Sum(p => p.Areas);
            int max = inList.Max(p => p.PRactangle.Location.X + p.PRactangle.Width);
            //max = inList.Max(p => p.Location.X + (p.IsWhirl ? p.Photo_Base_Info.PixFactHeigth : p.Photo_Base_Info.PixFactWidth) + ((p.BarCodeStatus == SmallERP.COM.Status.PhotoBarCodeStatus.RightOrLeft) ? BARCODEWIDTH : 0));
            double ALLAreas = boardHeight * max;
            double currWaste = 1 - UsefulAreas / ALLAreas;
            if ((currWaste <= inWaste))
            {
                outWaste = currWaste;
                return true;

            }
            else
            {
                outWaste = 0;
                return false;
            }
        }
        double CheckWaste(List<MyRectangle> inList, int boardHeight)
        {
            if (inList == null || inList.Count == 0)
            {

                return 0;
            }
            //double ALLAreas = inList.Sum(p => p.Areas);
            double UsefulAreas = inList.Where(w => w.isUsefull).Sum(p => p.Areas);
            //double UsefulAll = inList.Sum(p => p.Areas);
            int max = inList.Max(p => p.PRactangle.Location.X + p.PRactangle.Width);
            double ALLAreas = boardHeight * max;
            double currWaste = 1 - UsefulAreas / ALLAreas;
            if (double.IsNaN(currWaste))
            {
                currWaste = 100;
            }

            return currWaste;
        }
        List<PhotoInfo_PinBan> FindSuitPhotosSmall(List<PhotoInfo_PinBan> inList, Rectangle currRang, PhotoBarCodeStatus barCodeStatus, out int LeftH, int putPhotoOrder)
        {

            int inHeigth = currRang.Height; int MaxWidth = currRang.Width;
            //var TEMP = inList.Where(g => g.PixFactWidth <= MaxWidth);
            //var TEMP1 inList= .Where(g => g.PixFactHeigth <= inHeigth);
            //var TEMP2 = inList.Where(g => g.PixFactWidth <= MaxWidth && g.PixFactHeigth <= inHeigth).OrderBy(or => or.PixFactHeigth);
            var photoSizeGroup = inList.Where(g => (g.PixFactWidth <= MaxWidth && g.PixFactHeigth <= inHeigth) || (g.PixFactWidth <= inHeigth && g.PixFactHeigth <= MaxWidth)).OrderByDescending(or => or.PixFactHeigth).GroupBy(p => p.PhotoSizePix).ToList();
            if (!photoSizeGroup.Any())
            {
                LeftH = currRang.Height;
                return null;
            }
            photoSizeGroup = photoSizeGroup.OrderByDescending(or => or.FirstOrDefault().PixFactHeigth).ToList();

            int sizeCount = photoSizeGroup.Count();
            iMageInfo[] sizeArray = new iMageInfo[sizeCount + 1];
            for (int i = 1; i <= sizeCount; i++)
            {
                iMageInfo sizeG = new iMageInfo();
                sizeG.Width = photoSizeGroup[i - 1].FirstOrDefault().PixFactWidth;
                sizeG.Height = photoSizeGroup[i - 1].FirstOrDefault().PixFactHeigth;
                sizeG.Count = photoSizeGroup[i - 1].Count();

                sizeArray[i] = sizeG;
            }
            Array array = sizeArray;
            //第一个参数 数组，第二个第三个 是宽高第四个是条码宽第五个是 容错宽 第六个是组合数 第7个一次取最多尺寸数
            Array sizeResult = null;
            int barcodeWidth = BARCODEWIDTH2;
            if (barCodeStatus == PhotoBarCodeStatus.NoBarCode)
            {
                barcodeWidth = 0;
            }
            sizeResult = InterFace.Function3(ref array, MaxWidth, inHeigth, barcodeWidth, BlackWidthLong[changeLevel], BlackWidthLong[changeLevel], BlackWidthLong[changeLevel]);//

            if (sizeResult.Length == 0)
            {
                throw new Exception("请确认已装入加密狗后再试");
            }

            iMageInfo[] arrResult = (iMageInfo[])sizeResult;
            if (arrResult[0].Count == 0)
            {
                LeftH = 0;
                return new List<PhotoInfo_PinBan>();
            }
            string Key = "";
            Dictionary<string, int> sizePair = new Dictionary<string, int>();
            List<PhotoInfo_PinBan> suitest = new List<PhotoInfo_PinBan>();

            Dictionary<int, int> orderAndNum = new Dictionary<int, int>();//orderid和缺少多少张就完成
            List<int> AddedPhotoidlist = new List<int>();
            for (int i = 0; i < arrResult.Length; i++)
            {
                List<PhotoInfo_PinBan> suitTemp = new List<PhotoInfo_PinBan>();
                var a = inList.Where(p => p.PixFactWidth == arrResult[i].Width && p.PixFactHeigth == arrResult[i].Height);
                var b = a.OrderByDescending(or => or.Priority);
                int icount = 0;
                foreach (var ph in b)
                {
                    if (AddedPhotoidlist.Contains(ph.PhotoId))
                    {
                        continue;
                    }
                    else
                    {
                        AddedPhotoidlist.Add(ph.PhotoId);
                        suitTemp.Add(ph);
                        icount++;
                        if (icount == arrResult[i].Count)
                        {
                            break;
                        }
                    }
                }
                //处理条码(int)PhotoBarCodeStatus
                if (barCodeStatus != PhotoBarCodeStatus.NoBarCode)
                {
                    if (arrResult[i].barCode == 0)
                    {
                        suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.RightOrLeft);

                    }
                    else
                    {
                        suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.TopOrBottom);
                    }
                }
                else
                {
                    suitTemp.ForEach(eh => eh.BarCodeStatus = (int)PhotoBarCodeStatus.NoBarCode);
                }
                //处理旋转
                if (arrResult[i].isRotate == 1)
                {
                    suitTemp.ForEach(en => en.IsWhirl = true);
                }
                else
                {
                    suitTemp.ForEach(en => en.IsWhirl = false);
                }
                suitest.AddRange(suitTemp);



            }

            //新的获取照片顺序的按照剩余照片最少的 产品的原则获取照片



            //确定照片的摆放顺序
            //Point leftTop = currRang.Location;//左上定点
            //Point leftBottom = new Point(currRang.Location.X, currRang.Location.Y + currRang.Height);//坐下顶点



            //suitest.Add(photoSizeGroup.FirstOrDefault());
            //suitest = suitest.OrderByDescending(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            if (putPhotoOrder == 0)
            {
                suitest = suitest.OrderBy(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            }
            else
            {
                suitest = suitest.OrderByDescending(p => (p.IsWhirl) ? p.PixFactHeigth : p.PixFactWidth).ToList();
            }
            int col = 0;
            int CurrHeight = currRang.Location.Y;
            foreach (var photo in suitest)
            {

                //计算合适的 照片的坐标
                if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.TopOrBottom)
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth + BARCODEWIDTH2;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth + BARCODEWIDTH2;
                    }

                }
                else if (photo.BarCodeStatus == (int)PhotoBarCodeStatus.RightOrLeft)
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth;
                    }
                }
                else
                {
                    if (photo.IsWhirl)
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactWidth;
                    }
                    else
                    {
                        photo.Location = new Point(currRang.Location.X, CurrHeight);
                        CurrHeight += photo.PixFactHeigth;
                    }
                }
                //if (photo.Location.X == 0 && photo.Location.Y == 0)
                //{

                //}

            }
            LeftH = inHeigth - CurrHeight + currRang.Location.Y;//还差多少可以填满

            if (LeftH <= 0)
            {

            }
            else
            {
                //if (putPhotoOrder == 0)
                //{ //suitest.ForEach(p => p.Location = new Point(p.Location.X, p.Location.Y + LeftH));
                //    foreach (var photo in suitest)
                //    {
                //        photo.Location = new Point(photo.Location.X, photo.Location.Y + LeftH);

                //    }
                //}
                //else
                //{

                //}
            }
            return suitest;

        }
        public List<PhotoInfo_PinBan> GetWaitPBPhotoList1(Tb_paperTemplate_Info inPutPaperTempte, int inPutPrinterID, int inPutTakeNum)
        {
            List<PhotoInfo_PinBan> outPutPhotoList = new List<PhotoInfo_PinBan>();
            using (newSampleYPDBEntities db = new newSampleYPDBEntities())
            {
                List<photoInfo> photoArr = db.proc_GetWaitPBPhotoInfo(inPutPrinterID, inPutPaperTempte.TempLateId, inPutTakeNum).ToList();
                outPutPhotoList.AddRange(ConvertPiToPi_PingBan(photoArr, inPutPrinterID, inPutPaperTempte.PaperTypeId, inPutPaperTempte.PaperFaceId, db));
            }
            return outPutPhotoList;
        }
        public List<PhotoInfo_PinBan> GetWaitPBPhotoList(Tb_paperTemplate_Info inPutPaperTempte, int inPutPrinterID, int inPutTakeNum)
        {
           

            List<PhotoInfo_PinBan> outPutPhotoList = new List<PhotoInfo_PinBan>();
            using (AdoEx adoEx = new AdoEx())
            {
                SqlParameter[] parms = new SqlParameter[3];
                parms[0] = new SqlParameter("printerId", SqlDbType.Int);
                parms[0].Value = inPutPrinterID;
                parms[1] = new SqlParameter("materialID", SqlDbType.Int);
                parms[1].Value = inPutPaperTempte.TempLateId;
                parms[2] = new SqlParameter("@BoxCount", SqlDbType.Int);

                parms[2].Value = inPutTakeNum;
                var reader = adoEx.ExecuteDataReader(CommandType.StoredProcedure, "[proc_GetWaitPBPhotoInfoAll]", parms);
                while (reader.Read())
                {
                    PhotoInfo_PinBan pi_PinBan = new PhotoInfo_PinBan();

                    pi_PinBan.IsWhirl = false;
                    pi_PinBan.Height = Convert.ToDouble(reader["Height"]);//Math.Round(pi.Height, 1);
                    pi_PinBan.Width = Convert.ToDouble(reader["Width"]);//Math.Round(pi.Width , 1);
                    pi_PinBan.Remark = reader["Remark"].ToString();
                    pi_PinBan.TotalNum = Convert.ToInt32(reader["TotalNum"]);
                    pi_PinBan.PixWidth = Convert.ToInt32(reader["PixWidth"]);
                    pi_PinBan.PixHeight = Convert.ToInt32(reader["PixHeight"]);
                    pi_PinBan.PicPath = reader["PicPath"].ToString();
                    pi_PinBan.OldPicPath = reader["OldPicPath"].ToString();
                    pi_PinBan.MakeUpNum = 1;
                    pi_PinBan.PhotoId = Convert.ToInt32(reader["PhotoId"]);
                    pi_PinBan.OrderInfoName = reader["OrderProductName"].ToString();
                    pi_PinBan.PhotoBarCode = reader["PhotoBarCode"].ToString(); ;
                    pi_PinBan.PhotoSize = pi_PinBan.Width + "*" + pi_PinBan.Height; //Math.Round(pi.Width + 0.04, 1) + "*" + Math.Round(pi.Height + 0.04, 1);
                    pi_PinBan.PhotoName = reader["PhotoName"].ToString(); ;
                    pi_PinBan.OrderProductId = Convert.ToInt32(reader["OrderProductId"]);
                    pi_PinBan.PaperFaceId = Convert.ToInt32(reader["PaperFaceId"]);
                    pi_PinBan.PaperFaceName = reader["PaperFaceName"].ToString();
                    pi_PinBan.PaperTypeID = Convert.ToInt32(reader["PaperTypeID"]);
                    pi_PinBan.PaperTypeName = reader["PaperTypeName"].ToString();
                    pi_PinBan.ShopName = reader["ShopName"].ToString(); ;
                    pi_PinBan.Priority = Convert.ToInt32(reader["Priority"]);
                    pi_PinBan.isPart = false;
                    pi_PinBan.IsInBoard = false;
                    pi_PinBan.IsClearBox = 0;
                    pi_PinBan.CtmName = reader["CtmName"].ToString(); ;

                    outPutPhotoList.Add(pi_PinBan);
                }

            }
            return outPutPhotoList;
        }
        public void GetPBInfo(int printId, int paperTemplateid, out decimal SurplusArea, out int UseCellQty, out decimal PBCellArea, out int PBTCellPhotoCount, out int PBSurplusPhotoCount)
        {

            using (AdoEx adoEx = new AdoEx())
            {
                SqlParameter[] parms = new SqlParameter[7];
                parms[0] = new SqlParameter("printerId", SqlDbType.Int);
                parms[0].Value = printId;
                parms[1] = new SqlParameter("materialID", SqlDbType.Int);
                parms[1].Value = paperTemplateid;
                parms[2] = new SqlParameter("PBSurplusArea", SqlDbType.Decimal);
                parms[2].Direction = ParameterDirection.Output;
                parms[3] = new SqlParameter("PBUseCellQty", SqlDbType.Int);
                parms[3].Direction = ParameterDirection.Output;
                parms[4] = new SqlParameter("PBCellArea", SqlDbType.Int);
                parms[4].Direction = ParameterDirection.Output;

                parms[5] = new SqlParameter("PBTCellPhotoCount", SqlDbType.Int);
                parms[5].Direction = ParameterDirection.Output;

                parms[6] = new SqlParameter("PBSurplusPhotoCount", SqlDbType.Int);
                parms[6].Direction = ParameterDirection.Output;

                adoEx.ExecuteNonQuery(CommandType.StoredProcedure, "proc_GetPBSurplusArea", parms);
                if (parms[2].Value is DBNull)
                {
                    SurplusArea = 0;
                }
                else
                {
                    SurplusArea = Convert.ToDecimal(parms[2].Value);
                }
                if (parms[3].Value is DBNull)
                {
                    UseCellQty =0;

                }
                else
                {
                    UseCellQty = Convert.ToInt32(parms[3].Value);
                }
                if (parms[4].Value is DBNull)
                {
                    PBCellArea = 0;
                }
                else
                {
                    PBCellArea = Convert.ToDecimal(parms[4].Value);
                }
                if (parms[5].Value is DBNull)
                {
                    PBTCellPhotoCount = 0;
                }
                else
                {
                    PBTCellPhotoCount = Convert.ToInt32(parms[5].Value);
 
                }
                if (parms[6].Value is DBNull)
                {
                    PBSurplusPhotoCount = 0;
                }
                else
                {
                    PBSurplusPhotoCount = Convert.ToInt32(parms[6].Value);
                }
            }
        }

        //		/// <summary>
        //		/// 获取要拼版的列表
        //		/// </summary>
        //		/// <param name="inPutPaperTempte"></param>
        //		/// <param name="inPutPrinterID"></param>
        //		/// <param name="inPutTakeNum"></param>
        //		/// <returns></returns>
        //		public List<PhotoInfo_PinBan> GetWaitPBPhotoList(Tb_paperTemplate_Info inPutPaperTempte, int inPutPrinterID, int inPutTakeNum) {
        //			List<PhotoInfo_PinBan> outPutPhotoList = new List<PhotoInfo_PinBan>();
        //			int waitPinBanPhoto = (int)PhotoStatus.DistributedPrinter;
        //			int orderNumal = (int)OrderInfoStatus.Doing;
        //			int TakeNum = inPutTakeNum;
        //			using (newSampleYPDBEntities db = new newSampleYPDBEntities()) {
        //				//先获取拼过一部分的片子
        //				//再添加进来新单子&&
        //				//List<photoInfo> photoList = db.photoInfo.Where(p => p.orderInfo.status == orderNumal && p.orderInfo.WorkOrderFlowList.Where(w => w.tb_Tech.TechType == 3 && w.Status == 1) != null && p.printerId == inPutPrinterID).ToList();
        //				var orderListPartPin = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Any(wf => (wf.tb_Tech.TechType ==  (int)TechType.print  ) && wf.Status == (int)OrderFlowListStatus.Useable)).ToList();
        //				orderListPartPin = orderListPartPin.Where(o => {
        //					var count = o.photoInfo.Count();
        //					var sd = o.photoInfo.Count(p => p.status == waitPinBanPhoto);
        //					return count != sd;
        //				}).ToList();
        ////				List<orderInfo> orderListPartPin = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Any(wf => (wf.tb_Tech.TechType == 3 || wf.tb_Tech.TechType == 10) && wf.Status == 1) && o.photoInfo.Count() != o.photoInfo.Count(p => p.status == waitPinBanPhoto)).ToList();
        //				//List<photoInfo> 
        //				//List<photoInfo> photoList=db.photoInfo.Where(p=>p.paperFace.PaperFaceID==inPutPaperTempte.PaperFaceId&&p.paperType.PaperTypeID==inPutPaperTempte.PaperTypeId&&p.status==);
        //
        //				foreach (orderInfo order in orderListPartPin) {
        ////					order.photoInfo.Load();
        ////					if (!order.photoInfo.IsLoaded) {
        //						var mat = order.WorkOrderFlowList.FirstOrDefault(c => c.tb_Tech.TechType == printTech);
        ////					mat.WorkOrderFlowList_Material.Load();
        //
        //					var material = mat.WorkOrderFlowList_Material.FirstOrDefault(c => c.WM_MaterialItem.Cid == paperType);
        //					if (material == null || inPutPaperTempte.MaterialItemId != material.MaterialID) {
        //						continue;
        //					}
        ////					order.photoInfo.Load();
        // 					var photos = order.photoInfo.Where(photo => photo.status == waitPinBanPhoto && photo.printerId == inPutPrinterID).ToList();
        //					outPutPhotoList.AddRange(ConvertPiToPi_PingBan(photos, inPutPrinterID, 1, 1, db));
        //				}
        //				int partNum = outPutPhotoList.GroupBy(p => p.OrderProductId).Count();
        //				int takeNum = (inPutTakeNum - partNum) < 0 ? 0 : (inPutTakeNum - partNum);
        //				List<orderInfo> orderListUnPin = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Any(wf => (wf.tb_Tech.TechType == 3 || wf.tb_Tech.TechType == 10) && wf.Status == 1) && o.photoInfo.Count(p => p.status == waitPinBanPhoto) == o.photoInfo.Count()).OrderByDescending(or => or.Priority).OrderBy(or => or.OrderProductId).Take(takeNum).ToList();
        //
        //				List<orderInfo>  orderListUnPin2 = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Any(wf => (wf.tb_Tech.TechType ==  3 || wf.tb_Tech.TechType == 10) && wf.Status == 1)).ToList();
        //				orderListUnPin = orderListUnPin.Where(o => {
        //					var count = o.photoInfo.Count();
        //					var sd = o.photoInfo.Count(p => p.status == waitPinBanPhoto);
        //					return count == sd;
        //				}).ToList();
        //
        //				foreach(var order in orderListUnPin) {
        //					var mat =
        //						order.WorkOrderFlowList.First(c => c.tb_Tech.TechType == printTech)
        //							.WorkOrderFlowList_Material.First(c => c.WM_MaterialItem.WM_Material_Class.Cid == paperType);
        //					if (inPutPaperTempte.MaterialItemId != mat.MaterialID) {
        //						continue;
        //					}
        //					var photos = order.photoInfo.Where(photo => photo.status == waitPinBanPhoto && photo.printerId == inPutPrinterID).ToList();
        //					outPutPhotoList.AddRange(ConvertPiToPi_PingBan(photos, inPutPrinterID, 1, 1, db));
        //				}
        //
        //			}
        //			return outPutPhotoList;
        //		}

        private List<PhotoInfo_PinBan> ConvertPiToPi_PingBan(List<photoInfo> piSource, int printerId, int paperTypeId, int paperFaceId, newSampleYPDBEntities db) //将photoinfo转换成PhotoInfo_PinBan
        {
            List<PhotoInfo_PinBan> photoList = new List<PhotoInfo_PinBan>();
            PhotoInfo_PinBan pi_PinBan;
            //if (PBorderNum <= 0)
            //{
            //    PBorderNum = 30;
            //}
            int photoStatus = (int)PhotoStatus.DistributedPrinter; //等待拼板
            int photoStatus2 = (int)PhotoStatus.PingBanInd; //正在拼板中
            List<int> orderProductIdList = new List<int>();
            //if (!pi.orderInfoReference.IsLoaded)
            //{
            //    pi.orderInfoReference.Load();
            //}
            piSource.ForEach(eh => eh.orderInfoReference.Load());
            foreach (IGrouping<int, photoInfo> pGroup in piSource.GroupBy(g => g.orderInfo.OrderProductId))
            {
                int orderproductid = pGroup.Key;
                bool ispicPart = false;
                int picnum = piSource.Where(p => p.orderInfo.OrderProductId == orderproductid).Count();
                int picAllNum = db.photoInfo.Where(p => p.orderInfo.OrderProductId == orderproductid && p.printerId == printerId && p.paperFace.PaperFaceID == paperFaceId && p.paperType.PaperTypeID == paperTypeId).Count();
                if (picAllNum != picnum)
                {
                    ispicPart = true;
                }
                foreach (photoInfo pi in pGroup)
                {
                    pi.status = (int)PhotoStatus.PingBanInd; //标记被占用,正在拼板中....

                    #region load data

                    if (!pi.orderInfo.Tb_OrderBagReference.IsLoaded)
                    {
                        pi.orderInfo.Tb_OrderBagReference.Load();
                    }
                    if (!pi.orderInfo.Tb_OrderBag.ShopReference.IsLoaded)
                    {
                        pi.orderInfo.Tb_OrderBag.ShopReference.Load();
                    }
                    if (!pi.paperFaceReference.IsLoaded)
                    {
                        pi.paperFaceReference.Load();
                    }
                    if (!pi.paperTypeReference.IsLoaded)
                    {
                        pi.paperTypeReference.Load();
                    }

                    #endregion

                    pi_PinBan = new PhotoInfo_PinBan();
                    pi_PinBan.IsWhirl = false;
                    pi_PinBan.Height = pi.Height;//Math.Round(pi.Height, 1);
                    pi_PinBan.Width = pi.Width;//Math.Round(pi.Width , 1);
                    pi_PinBan.Remark = pi.Remark;
                    pi_PinBan.TotalNum = pi.TotalNum == null ? 0 : (int)pi.TotalNum;
                    pi_PinBan.PixWidth = pi.pixWidth;
                    pi_PinBan.PixHeight = pi.pixHeight;
                    pi_PinBan.PicPath = pi.picPath;
                    pi_PinBan.OldPicPath = pi.OldPicPath;
                    pi_PinBan.MakeUpNum = pi.MakeUpNum == null ? 0 : (int)pi.MakeUpNum;
                    pi_PinBan.PhotoId = pi.photoId;
                    pi_PinBan.OrderInfoName = pi.orderInfo.OrderProductName;
                    pi_PinBan.PhotoBarCode = pi.PhotoBarCode;
                    pi_PinBan.PhotoSize = pi.Width + "*" + pi.Height; //Math.Round(pi.Width + 0.04, 1) + "*" + Math.Round(pi.Height + 0.04, 1);
                    pi_PinBan.PhotoName = pi.photoName;
                    pi_PinBan.OrderProductId = pi.orderInfo.OrderProductId;

                    pi_PinBan.ShopName = pi.orderInfo.Tb_OrderBag.Shop.shopName;
                    pi_PinBan.Priority = pi.orderInfo.Priority == null ? 0 : (int)pi.orderInfo.Priority;
                    pi_PinBan.isPart = ispicPart;
                    pi_PinBan.IsInBoard = false;
                    pi_PinBan.IsClearBox = pi.status2;
                    pi_PinBan.CtmName = pi.orderInfo.CtmName;
                    if (!orderProductIdList.Contains(pi_PinBan.OrderProductId))
                    {
                        orderProductIdList.Add(pi_PinBan.OrderProductId);
                    }
                    //					if (PBorderNum > 0) {
                    //						if (orderProductIdList.Count > PBorderNum) {
                    //							return photoList;
                    //						}
                    //					}
                    photoList.Add(pi_PinBan);
                }
            }
            return photoList;
        }
        //		/// <summary>获取要拼版的列表</summary>
        //		/// <param name="inPutPaperTempte"></param>
        //		/// <param name="inPutPrinterID"></param>
        //		/// <param name="inPutTakeNum"></param>
        //		/// <returns></returns>
        //		public List<PhotoInfo_PinBan> GetSmallWaitPBPhotoList(Tb_paperTemplate_Info inPutPaperTempte, int inPutPrinterID, int inPutTakeNum,int mid) {
        //			List<PhotoInfo_PinBan> outPutPhotoList = new List<PhotoInfo_PinBan>();
        //			int waitPinBanPhoto = (int)PhotoStatus.DistributedPrinter;
        //			int orderNumal = (int)OrderInfoStatus.Doing;
        //			int TakeNum = inPutTakeNum;
        //			double samllSize = 8;
        //			int samllCount = 5;
        //			using (newSampleYPDBEntities db = new newSampleYPDBEntities()) {
        //				//先获取拼过一部分的片子
        //				//再添加进来新单子&&
        //				//List<photoInfo> photoList = db.photoInfo.Where(p => p.orderInfo.status == orderNumal && p.orderInfo.WorkOrderFlowList.Where(w => w.tb_Tech.TechType == 3 && w.Status == 1) != null && p.printerId == inPutPrinterID).ToList();
        //				List<orderInfo> orderListPartPin = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Where(wf => (wf.tb_Tech.TechType == 3 || wf.tb_Tech.TechType == 10) && wf.Status == 1).Count() > 0 && o.photoInfo.Count(p => p.status == waitPinBanPhoto) == o.photoInfo.Count() && (decimal)(o.photoInfo.Count(p => p.Height < samllSize || p.Width < samllSize)) / o.photoInfo.Count() > 0.3m).OrderByDescending(or => or.Priority).OrderBy(or => or.OrderProductId).Take(inPutTakeNum).ToList(); ;
        //				//List<photoInfo> 
        //				//List<photoInfo> photoList=db.photoInfo.Where(p=>p.paperFace.PaperFaceID==inPutPaperTempte.PaperFaceId&&p.paperType.PaperTypeID==inPutPaperTempte.PaperTypeId&&p.status==);
        //
        //				foreach (orderInfo order in orderListPartPin) {
        //					if (!order.photoInfo.IsLoaded) {
        //						 
        //						order.photoInfo.Load();
        //						var mat = order.WorkOrderFlowList.First(c => c.tb_Tech.TechType == printTech).WorkOrderFlowList_Material.First(c => c.WM_MaterialItem.WM_Material_Class.Cid == paperType);
        //						if (inPutPaperTempte.MaterialItemId != mat.MaterialID) {
        //							continue;
        //						}
        //						//order.WorkOrderFlowList.Load();
        //						//order.WorkOrderFlowList.ToList().ForEach(wf=>wf.tb_TechReference.Load());
        //						//if (order.WorkOrderFlowList.Where(wf => wf.tb_Tech.TechType == 3 && wf.Status == 1).Count() < 1)
        //						//{
        //						//    continue;
        //
        //						//}
        //						//order.photoInfo.ToList().ForEach(p=>p.paperFaceReference.Load()&&p.paperTypeReference.Load());
        ////						var photoList = db.proc_GetWaitPBPhotoInfo(inPutPrinterID, mid).ToList();
        //						foreach (photoInfo photo in order.photoInfo) {
        ////							photo.paperFaceReference.Load();
        ////							photo.paperTypeReference.Load();
        //							if (photo.status != waitPinBanPhoto || photo.printerId != inPutPrinterID) {
        //								continue;
        //							}
        //							PhotoInfo_PinBan rtnPhoto = new PhotoInfo_PinBan();
        //							rtnPhoto.BarCodeStatus = (int)PhotoBarCodeStatus.RightOrLeft;
        //							rtnPhoto.CtmName = order.CtmName;
        //							rtnPhoto.IsAutoPB = false;
        //							rtnPhoto.IsClearBox = 0;
        //							rtnPhoto.IsInBoard = false;
        //							rtnPhoto.IsWhirl = false;
        //							rtnPhoto.Location = new Point(0, 0);
        //							rtnPhoto.OldPicPath = photo.OldPicPath;
        //							rtnPhoto.OrderInfoName = order.OrderProductName;
        //							rtnPhoto.OrderProductId = order.OrderProductId;
        //							rtnPhoto.PaperFaceId = inPutPaperTempte.PaperFaceId;
        ////							rtnPhoto.PaperFaceName = inPutPaperTempte.PaperFaceName;
        ////							rtnPhoto.PaperTypeID = inPutPaperTempte.PaperTypeId;
        //							rtnPhoto.PaperTypeName = inPutPaperTempte.PaperTypeName;
        //							rtnPhoto.PhotoBarCode = photo.PhotoBarCode;
        //							rtnPhoto.PhotoId = photo.photoId;
        //							rtnPhoto.PhotoName = photo.photoName;
        //							rtnPhoto.PicPath = photo.picPath;
        //							rtnPhoto.PixHeight = photo.pixHeight;
        //							rtnPhoto.PixWidth = photo.pixWidth;
        //							rtnPhoto.PrinterId = inPutPrinterID;
        //							//rtnPhoto.Priority = order.Priority;
        //							rtnPhoto.Remark = photo.Remark;
        //							rtnPhoto.Status = photo.status;
        //							rtnPhoto.Width = photo.Width;
        //							rtnPhoto.Height = photo.Height;
        //							outPutPhotoList.Add(rtnPhoto);
        //						}
        //					}
        //
        //				}
        //				int partNum = outPutPhotoList.GroupBy(p => p.OrderProductId).Count();
        //				List<orderInfo> orderListUnPin = db.orderInfo.Where(o => o.status == orderNumal && o.WorkOrderFlowList.Where(wf => (wf.tb_Tech.TechType == 3 || wf.tb_Tech.TechType == 10) && wf.Status == 1).Count() > 0 && o.photoInfo.Count(p => p.status == waitPinBanPhoto) == o.photoInfo.Count()).OrderByDescending(or => or.Priority).OrderBy(or => or.OrderProductId).ToList();
        //
        //				foreach (orderInfo order in orderListUnPin) {
        //					if (!order.photoInfo.IsLoaded) {
        //						var mat = order.WorkOrderFlowList.First(c => c.tb_Tech.TechType == printTech).WorkOrderFlowList_Material.First(c => c.WM_MaterialItem.WM_Material_Class.Cid == paperType);
        //						if (inPutPaperTempte.MaterialItemId != mat.MaterialID) {
        //							continue;
        //						}
        //						var photoList = db.proc_GetWaitPBPhotoInfo(inPutPrinterID, mid).ToList();
        //						foreach (photoInfo photo in photoList) {
        ////							photo.paperFaceReference.Load();
        ////							photo.paperTypeReference.Load();
        //							if (photo.status != waitPinBanPhoto || photo.printerId != inPutPrinterID) {
        //								continue;
        //							}
        //							PhotoInfo_PinBan rtnPhoto = new PhotoInfo_PinBan();
        //							rtnPhoto.BarCodeStatus = (int)PhotoBarCodeStatus.RightOrLeft;
        //							rtnPhoto.CtmName = order.CtmName;
        //							rtnPhoto.IsAutoPB = false;
        //							rtnPhoto.IsClearBox = 0;
        //							rtnPhoto.IsInBoard = false;
        //							rtnPhoto.IsWhirl = false;
        //							rtnPhoto.Location = new Point(0, 0);
        //							rtnPhoto.OldPicPath = photo.OldPicPath;
        //							rtnPhoto.OrderInfoName = order.OrderProductName;
        //							rtnPhoto.OrderProductId = order.OrderProductId;
        //							rtnPhoto.PaperFaceId = inPutPaperTempte.PaperFaceId;
        ////							rtnPhoto.PaperFaceName = inPutPaperTempte.PaperFaceName;
        ////							rtnPhoto.PaperTypeID = inPutPaperTempte.PaperTypeId;
        //							rtnPhoto.PaperTypeName = inPutPaperTempte.PaperTypeName;
        //							rtnPhoto.PhotoBarCode = photo.PhotoBarCode;
        //							rtnPhoto.PhotoId = photo.photoId;
        //							rtnPhoto.PhotoName = photo.photoName;
        //							rtnPhoto.PicPath = photo.picPath;
        //							rtnPhoto.PixHeight = photo.pixHeight;
        //							rtnPhoto.PixWidth = photo.pixWidth;
        //							rtnPhoto.PrinterId = inPutPrinterID;
        //							//rtnPhoto.Priority = order.Priority;
        //							rtnPhoto.Remark = photo.Remark;
        //							rtnPhoto.Status = photo.status;
        //							rtnPhoto.Width = photo.Width;
        //							rtnPhoto.Height = photo.Height;
        //							outPutPhotoList.Add(rtnPhoto);
        //						}
        //					}
        //
        //				}
        //
        //			}
        //			return outPutPhotoList;
        //		}
        public List<DisPalyBoardInfo> GetUnSureBan()
        {
            List<DisPalyBoardInfo> rtnList = new List<DisPalyBoardInfo>();
            int unSureStatus = (int)EnumBoardStatus.WaitSure;
            using (newSampleYPDBEntities db = new newSampleYPDBEntities())
            {
                List<Board> listBoard = db.Board.Where(b => b.status == unSureStatus).ToList();
                foreach (Board board in listBoard)
                {
                    DisPalyBoardInfo disPlayBoard = new DisPalyBoardInfo();
                    disPlayBoard.BoardID = board.BoardId;
                    disPlayBoard.FactLength = board.length;
                    //disPlayBoard.Height = board.width;
                    disPlayBoard.Length = board.length;
                    disPlayBoard.Selected = false;
                    disPlayBoard.UserfulNum = (decimal)(1 - board.WasteRate) * 100;
                    //disPlayBoard.Width = board.width;

                    int TemplateID = board.TempleteID;
                    tb_paperTemplate paperTemplate = db.tb_paperTemplate.FirstOrDefault(pt => pt.TempLateId == TemplateID);
                    paperTemplate.paperFaceReference.Load();
                    paperTemplate.paperTypeReference.Load();
                    //board.WM_MaterialItemReference.Load();
                    disPlayBoard.BoardTemplate = new Tb_paperTemplate_Info()
                    {
                        BoardHeight = paperTemplate.boardHeight,
                        BoardLength = paperTemplate.boardLength,
                        PaperFaceId = paperTemplate.paperFace.PaperFaceID,
                        PaperFaceName = paperTemplate.paperFace.Name,
                        PaperTypeId = paperTemplate.paperType.PaperTypeID,
                        PaperTypeName = paperTemplate.paperType.Name,
                        TempLateId = paperTemplate.TempLateId,
                        TemplateName = paperTemplate.TemplateName,
                        //MaterialItemId = paperTemplate.MaterialItemID ?? 0,
                    };
                    board.picMakeUp.Load();
                    disPlayBoard.PhotoNum = board.picMakeUp.Count;
                    //disPlayBoard.MaterialItemName = board.WM_MaterialItem == null ? "" : board.WM_MaterialItem.Name;

                    //List<PhotoInfo_PinBan> listPhoto = new List<PhotoInfo_PinBan>();
                    //board.picMakeUp.Load();
                    //foreach (picMakeUp pmu in board.picMakeUp)
                    //{
                    //    pmu.photoInfoReference.Load();
                    //    PhotoInfo_PinBan pip = new PhotoInfo_PinBan();
                    //    pip.BarCodeStatus = 0;
                    //    pip.

                    //}
                    rtnList.Add(disPlayBoard);
                }

            }

            return rtnList;
        }

        public int DeleteBoards(List<int> BoardIDList)
        {
            int rtn = -1;
            int waitPin = (int)PhotoStatus.DistributedPrinter;
            try
            {
                using (newSampleYPDBEntities db = new newSampleYPDBEntities())
                {
                    foreach (int boardid in BoardIDList)
                    {
                        Board b = db.Board.FirstOrDefault(p => p.BoardId == boardid);
                        if (b != null)
                        {
                            List<photoInfo> phList = db.photoInfo.Where(p => p.picMakeUp.FirstOrDefault().Board.BoardId == boardid).ToList();
                            foreach (photoInfo photo in phList)
                            {
                                photo.status = waitPin;
                            }
                            db.DeleteObject(b);
                        }
                        db.SaveChanges();

                    }
                }
            }
            catch (Exception exxx)
            {
                rtn = -1;
            }
            return rtn;
        }

        public int SaveBoards(List<int> BoardIDList)
        {
            int rtn = -1;
            //int waitPin=(int)PhotoStatus.w;
            try
            {
                using (newSampleYPDBEntities db = new newSampleYPDBEntities())
                {
                    foreach (int boardid in BoardIDList)
                    {
                        Board b = db.Board.FirstOrDefault(p => p.BoardId == boardid);
                        //if (b != null)
                        //{
                        //    List<photoInfo> phList = db.photoInfo.Where(p => p.picMakeUp.FirstOrDefault().Board.BoardId == boardid).ToList();
                        //    foreach (photoInfo photo in phList)
                        //    {
                        //        //photo.status = waitPin;
                        //    }
                        //}
                        b.status = (int)EnumBoardStatus.waitProduct;
                        db.SaveChanges();

                    }
                }
            }
            catch (Exception exxx)
            {
                rtn = -1;
            }
            return rtn;
        }
        public  int GridQty(int printId)
        {
            using (newSampleYPDBEntities db = new newSampleYPDBEntities())
            {
                var firstOrDefault = db.GridSubArea.FirstOrDefault(c => c.printer.Any(d => d.PrinterID == printId));
                if (firstOrDefault != null)
                {
                    return firstOrDefault.widthNum * firstOrDefault.heightNum;
                }
            }
            return 0;
        }

    }



}

